package coop.bancocredicoop.proyectos.gd.servlet;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import coop.bancocredicoop.proyectos.gd.FrontEndMessage;
import coop.bancocredicoop.proyectos.gd.Usuario;
import coop.bancocredicoop.proyectos.gd.domain.Document;
import coop.bancocredicoop.proyectos.gd.procedure.CorregirDocumentoProcedure;
import coop.bancocredicoop.proyectos.gd.query.document.FindDocumentById;
import coop.bancocredicoop.proyectos.gd.query.documentType.FindAllDocumentTypeOrderByName;
import coop.bancocredicoop.proyectos.gd.query.documentType.FindDocumentTypeById;

public class CorregirDocumentoServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	private static final Log log = LogFactory.getLog(CorregirDocumentoServlet.class);
	private static final String listarArchivosJsp = "/jsp/listarArchivos/index.jsp";
	private static final String documentosRecientesJsp = "/jsp/documentosRecientes/index.jsp";
	private static final String altaDocumento = "/jsp/altaDocumento/index.jsp";

	private static final String indexJsp = "/jsp/corregirDocumento/index.jsp";

	@Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		try {

			/*
			 * Carga de algunos atributos necesarios para el render de la pagina.
			 */
			Document document = new FindDocumentById().
					run(Long.valueOf(request.getParameter("documentId")));

			request.setAttribute("listDocumentType", new FindAllDocumentTypeOrderByName().run());

			request.setAttribute("documentId", String.valueOf(document.getId()));
			request.setAttribute("customerId", document.getCustomer().getIdPersona());
			request.setAttribute("customerDescription",
					document.getCustomer().getIdPersona() +
					" (denominacion: " + document.getCustomer().getName() +
					", CUIT:" + document.getCustomer().getCuit() + ")");
			request.setAttribute("documentType", String.valueOf(document.getDocumentType().getId()));
			request.setAttribute("purgeable", String.valueOf(document.getDocumentType().getPurgeable()));
			request.setAttribute("box", document.getBox().getCajaId());
			request.setAttribute("expirationDate",
					new SimpleDateFormat("dd/MM/yyyy").format(document.getValidTo()));
			request.setAttribute("notes", document.getNotes());

			/*
			 * Forward de la pagina. 
			 */
			getServletContext().getRequestDispatcher(indexJsp).
					forward(request, response);

		} catch (Exception e) {
			e.printStackTrace();
		}

    }
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		try {
			// Create a new file upload handler
			ServletFileUpload upload = new ServletFileUpload();

			// Parse the request
			FileItemIterator iter = upload.getItemIterator(request);

			while (iter.hasNext()) {
				FileItemStream item = iter.next();
				String name = item.getFieldName();
				InputStream stream = item.openStream();

				if (item.isFormField()) {
					request.setAttribute(name, Streams.asString(stream));
					//stream.close();
				} else {
					request.setAttribute(name, item.getName());

					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					Streams.copy(stream, baos, /* close stream */ true);
					baos.close();

					request.setAttribute(name + "ByteArray", baos.toByteArray());
				}
			}

			_doPost(request, response);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

	}

	/*
	 * doPost propiamente dicho, donde la accion transcurre
	 */
	private void _doPost(HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		/*
		 * Carga de algunos atributos necesarios para el render de la pagina.
		 */
		request.setAttribute("listDocumentType", new FindAllDocumentTypeOrderByName().run());
		request.setAttribute("purgeable", String.valueOf(new FindDocumentTypeById().run(
				Long.valueOf((String)request.getAttribute("documentType"))).getPurgeable()));

		/*
		 * Validaciones
		 */
		List<String> listError = new LinkedList<String>();

		if (request.getAttribute("box") == null ||
				((String)request.getAttribute("box")).trim().equals(""))
			listError.add("Debe ingresar una caja.");

		try {
			new SimpleDateFormat("dd/MM/yyyy").parse((String)request.getAttribute("expirationDate"));
		} catch (ParseException e) {
			listError.add("La fecha ingresada no es correcta.");
		}

		request.setAttribute("listError", listError);

		/*
		 * Para el caso en el que haya errores...
		 */
		if (!listError.isEmpty()) {
			getServletContext().getRequestDispatcher(indexJsp).
				forward(request, response);

			return;
		}

		/*
		 * Una vez pasada las validaciones...
		 */
		new CorregirDocumentoProcedure().run(
				Long.valueOf((String)request.getAttribute("documentId")),
				((Usuario)request.getSession().getAttribute("usuario")).getUserName(),
				Long.valueOf((String)request.getAttribute("customerId")),
				(String)request.getAttribute("box"),
				Long.valueOf((String)request.getAttribute("documentType")),
				new SimpleDateFormat("dd/MM/yyyy").parse((String)request.getAttribute("expirationDate")),
				null,
				(String)request.getAttribute("inputDocument") != null &&
						!((String)request.getAttribute("inputDocument")).trim().equals("") ?
						(byte[])request.getAttribute("inputDocumentByteArray") :
						null,
				(String)request.getAttribute("notes")
				);

		/*
		 * Mensaje de exito.
		 */
		FrontEndMessage frontEndMessage = new FrontEndMessage();
		frontEndMessage.setSuccessMessage("Se ha corregido el documento.");
		frontEndMessage.setMessagesInSession(request);

		/*
		 * Redireccion a la pagina de documentos recientes.
		 */
		response.sendRedirect(request.getContextPath() + documentosRecientesJsp);

	}

}
